package net.melon.product.inst.service.impl;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;

import javax.annotation.Resource;

import net.esj.basic.dao.jdbc.JdbcDao;
import net.esj.basic.dao.querybuilder.QueryBuilder;
import net.esj.basic.exception.MelonException;
import net.esj.basic.service.impl.DefaultServiceImpl;
import net.esj.basic.utils.Assert;
import net.esj.basic.utils.Validators;
import net.melon.jdbc.core.RowMapper;
import net.melon.product.inst.service.SpecificationsService;
import net.melon.product.pojo.ProductSpecifications;
import net.melon.product.pojo.ProductSpecificationsValue;
import net.melon.product.pojo.ProductTypeSpecificationsLink;
import net.melon.product.pojo.dto.ProductSpecificationsValueDto;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service("specificationsService")
public class SpecificationsServiceImpl extends DefaultServiceImpl implements SpecificationsService {
	
	@Resource
	private SpecificationsValueCacheProxy specificationsValueCacheProxy;
	
	@Transactional
	@Override
	public void addValueList(ProductSpecificationsValueDto valueDto) {
		List<ProductSpecificationsValue> list = getProductSpecificationsValueList(valueDto.getProductSpecifications().getId());
		HashMap<Long, ProductSpecificationsValue> map = new HashMap<Long, ProductSpecificationsValue>();
		for(ProductSpecificationsValue v : list){
			v.setState(-1);
			map.put(v.getId(), v);
		}
		for(ProductSpecificationsValue v : valueDto.getList()){
			if(v.getId()==null){
				v.setState(1);
				v.setSpecifications(valueDto.getProductSpecifications());
				specificationsValueCacheProxy.saveProductSpecificationsValue(v);
			}else if(map.containsKey(v.getId())){
				v.setState(1);
				v.setSpecifications(valueDto.getProductSpecifications());
				map.put(v.getId(), v);
			}
		}
		for(ProductSpecificationsValue v : map.values()){
			specificationsValueCacheProxy.updateProductSpecificationsValue(v);
		}
	}
	
	@Override
	public ProductSpecificationsValueDto getValueDto(Long specificationsId) {
		ProductSpecificationsValueDto dto = new ProductSpecificationsValueDto();;
		ProductSpecifications p = get(specificationsId, ProductSpecifications.class);
		Assert.notNull(p);
		dto.setProductSpecifications(p);
		List<ProductSpecificationsValue> list = getProductSpecificationsValueList(specificationsId);
		if(!Validators.isEmpty(list)){
			dto.setList(list);
		}
		return dto;
	}
	
	private static final String LIST_SPECIFICATIONS_SQL = "SELECT * FROM ML_PRODUCT_SPECIFICATIONS_VALUE WHERE SPECIFICATIONS_ID = ? AND STATE = 1 ";
	
	@Override
	public List<ProductSpecificationsValue> getProductSpecificationsValueList(final Long specificationsId) {
		List<ProductSpecificationsValue> list = getDao(JdbcDao.class).getJdbcTemplate().query(LIST_SPECIFICATIONS_SQL,
				new RowMapper<ProductSpecificationsValue>() {
					@Override
					public ProductSpecificationsValue mapRow(ResultSet arg0, int arg1)
							throws SQLException {
						ProductSpecificationsValue pv = new ProductSpecificationsValue();
						pv.setId(arg0.getLong("ID"));
						pv.setSpecifications(new ProductSpecifications(specificationsId));
						pv.setValue(arg0.getString("VALUE"));
						pv.setState(arg0.getInt("STATE"));
						return pv;
					}
				},new Object[]{specificationsId});
		
		return list;
	}

	@Override
	public List<ProductSpecifications> specificationsLink() {
		QueryBuilder<ProductSpecifications> qb = createQueryBuilder(ProductSpecifications.class);
		qb.eq("state", 1);
		return queryListByQueryBuilder(qb);
	}

	@Override
	public void deleteSpecifications(Long id) {
		QueryBuilder<ProductTypeSpecificationsLink> qb = createQueryBuilder(ProductTypeSpecificationsLink.class);
		qb.eq("specifications.id", id).eq("state", 1);
		if(queryCountByQueryBuilder(qb)>0){
			throw new MelonException("该规格已经使用不能删除");
		}
		ProductSpecifications p = get(id, ProductSpecifications.class);
		p.setState(-1);
	}

}
